import base64
import urllib2

from basecamp import Basecamp
from xml.etree import ElementTree as ET
from cache import Cache

class BCAPI(Basecamp):
    '''Derive from Basecamp class'''

    def __init__(self, account):
        baseURL = account.link
        username = account.username
        password = base64.standard_b64decode(account.password)
        self.cache = Cache()
        self.set_nocache(False)

        self.baseURL = baseURL
        if self.baseURL[-1] == '/':
            self.baseURL = self.baseURL[:-1]

        #find protocol, url
        protocol_pos = baseURL.find('://')
        url = baseURL[protocol_pos + 3:]
        protocol = baseURL[:protocol_pos]

        passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
        passman.add_password(None, url, username, password)
        authhandler = urllib2.HTTPBasicAuthHandler(passman)

        self.opener = urllib2.build_opener(authhandler)
        self.opener.addheaders = [
              ('Content-Type', 'application/xml'),
              ('Accept', 'application/xml')]

    def set_nocache(self, flag):
        self.nocache = bool(flag)

    def projects(self):
        path = '/projects.xml'
        data = self._fetch(path) 
        return ET.fromstring(data).getiterator('project')

    def report(self, query={}):
        q = {
            'from': '',
            'to': '',
            'subject_id': '',
            'todo_item_id': '',
            'filter_project_id': '',
            'filter_company_id': '',
        }

        q.update(query)
        
        q = '&'.join(['%s=%s' % (k, v) for k, v in q.items()])
        path = '/time_entries/report.xml?' + q
        data = self._fetch(path)
        return ET.fromstring(data).getiterator('time-entry')

    def me(self):
        path = '/me.xml'
        data = self._fetch(path)
        return ET.fromstring(data).getiterator('person').pop()
    
    def _fetch(self, path):
        '''Fetch data from source if not in cache.'''
        cache = self.cache.get(path)
        if self.nocache or not cache: 
            data = self._request(path)
            self.cache.set(path, data)
        else:
            data = cache.data
       
        return data 
